use ndarray::{array, Array2};
use rstest::rstest;

use crate::tests::fixtures::{rand_usize, RANDOM_USIZE};
use crate::tiling::slot_grid::tests::{
    create_grid_slot_or_none,
    create_test_slot_grid,
    pad_coordinates_randomly,
    pad_grid_randomly,
};
use crate::tiling::GridSlot;

// noinspection DuplicatedCode
#[rstest]
// region valid 1,1, true
#[case::valid_1_1_true(
    pad_coordinates_randomly((1, 1)),
    pad_grid_randomly(array![
        [None, None],
        [
            None,
            create_grid_slot_or_none(),
        ],
        [
            None,
            create_grid_slot_or_none(),
        ],
    ]),
    true,
)]
// endregion
// region valid 2,3, true
#[case::valid_2_3_true(
    pad_coordinates_randomly((2, 3)),
    pad_grid_randomly(array![
        [None, None, None, None],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
    ]),
    true,
)]
// endregion
// region valid 0,3, past north, false
#[case::valid_0_3_past_north_false(
    (0, rand_usize(1, 4)),
    pad_grid_randomly(array![
        [None, None, None, None],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
    ]),
    false,
)]
// endregion
// region valid 2,4, past east, false
#[case::valid_2_4_past_east_false(
    (rand_usize(1, 3), 4 + *RANDOM_USIZE * 4),
    pad_grid_randomly(array![
        [None, None, None, None],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
    ]),
    false,
)]
// endregion
// region valid 3,3, past south, false
#[case::valid_3_3_past_south_false(
    (3 + *RANDOM_USIZE * 3, rand_usize(1, 3)),
    pad_grid_randomly(array![
        [None, None, None, None],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
    ]),
    false,
)]
// endregion
// region valid 3,0, past west, false
#[case::valid_3_0_past_west_false(
    (rand_usize(1, 4), 0),
    pad_grid_randomly(array![
        [None, None, None, None],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
    ]),
    false,
)]
// endregion
// region invalid 30,40, far outside, false
#[case::invalid_30_40_far_outside_false(
    (rand_usize(30, 50), rand_usize(40, 60)),
    pad_grid_randomly(array![
        [None, None, None, None],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
        [
            None,
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
            create_grid_slot_or_none(),
        ],
    ]),
    false,
)]
// endregion
fn test_coordinates_are_in_borders(
    #[case] coordinates: (usize, usize),
    #[case] grid: Array2<Option<GridSlot>>,
    #[case] expected_result: bool,
) {
    let mut slot_grid = create_test_slot_grid(true, false);
    slot_grid.grid = grid;
    let slot_grid = slot_grid;

    let result: bool = slot_grid.coordinates_are_in_borders(coordinates);

    assert_eq!(result, expected_result);
    // Access slot_grid to ensure it was not moved.
    drop(slot_grid);
}
